package com.sponge.dao.imp;

import com.sponge.dao.BaseDao;
import com.sponge.utils.JdbcUtils;
import com.sponge.utils.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.sql.*;

public class BaseDaoImpl<T> implements BaseDao {

    protected Connection connection = null;
    protected PreparedStatement preparedStatement = null;
    protected ResultSet resultSet = null;
    private StringUtils stringUtils = new StringUtils();

    public boolean update(String sql, Object[] parameters) {
        try {
            connection = JdbcUtils.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < parameters.length; i++) {
                preparedStatement.setObject(i + 1, parameters[i]);
            }
            return 1  == preparedStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
//            release(resultSet, preparedStatement, connection);
        }
        return false;
    }

    public T query(String sql,Object[] parameters){
        T t = null;
        try {
            connection = JdbcUtils.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < parameters.length; i++) {
                preparedStatement.setObject(i+1,parameters[i]);
            }
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                Class<T> entityClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
                t = entityClass.getDeclaredConstructor().newInstance();
                ResultSetMetaData metaData = resultSet.getMetaData();
                for (int i = 0; i < metaData.getColumnCount(); i++) {
                    String columnName = metaData.getColumnName(i + 1);
                    String setterName = stringUtils.getSetterName(columnName);
                    Method method = entityClass.getMethod(setterName, Class.forName(metaData.getColumnClassName(i + 1)));
                    method.invoke(t, resultSet.getObject(columnName));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return t;
    }
}
